package es.ucm.fdi.xtremeaudio.controlador;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import es.ucm.fdi.xtremeaudio.modelo.beans.Biblioteca;
import es.ucm.fdi.xtremeaudio.modelo.beans.Bean;
import es.ucm.fdi.xtremeaudio.modelo.beans.Playlist;
import es.ucm.fdi.xtremeaudio.modelo.fachada.Fachada;
import es.ucm.fdi.xtremeaudio.modelo.beans.Cancion;
import es.ucm.fdi.xtremeaudio.vista.FormAyuda;
import es.ucm.fdi.xtremeaudio.vista.FormPrincipal;
import es.ucm.fdi.xtremeaudio.vista.FormTags;
import es.ucm.fdi.xtremeaudio.vista.NodoArbol;

import javazoom.jlgui.basicplayer.BasicPlayer;

public class Controlador {

	static FormPrincipal vistaPrincipal;
	static FormAyuda vistaAyuda;
	static FormTags vistaTags;

	public static void minimizar() {
		vistaPrincipal.getVentana().setExtendedState(JFrame.ICONIFIED);
	}

	public static void salir(int i) {
		System.exit(i);
	}

	public static void minimizarAyuda() {
		vistaAyuda.getVentana().setExtendedState(JFrame.ICONIFIED);
	}

	public static void cerrarAyuda() {
		vistaAyuda.hide();
	}

	public static void minimizarTags() {
		vistaTags.getVentana().setExtendedState(JFrame.ICONIFIED);
	}

	public static void cerrarTags() {
		vistaTags.hide();
	}

	public static void guardarTags() {
		vistaTags.hide();
		String autor = vistaTags.getFieldAutor().getText();
		String album = vistaTags.getFieldAlbum().getText();
		String titulo = vistaTags.getFieldTitulo().getText();
		String genero = vistaTags.getFieldGenero().getText();
		String anyo = vistaTags.getFieldAnyo().getText();
		String pista = vistaTags.getFieldPista().getText();
		Cancion oCancion = new Cancion(-1, autor, album, titulo, genero, anyo,
				pista, -1, "", "", "");
		oCancion.setPista(pista);
		Bean bean = Fachada.guardarTags(oCancion);
		if (bean != null) {

			// Actualizar Vista
			actualizaTablaLista(bean);
			actualizaTablaInfo(bean);
		}
	}

	public static void cargarBiblioteca() {
		Bean bean = Fachada.cargarBiblioteca();
		creaArbol(bean);
		if (bean != null) {			
			actualizaReproduccion(bean);
		} else {
			JOptionPane.showMessageDialog(null,
					"Error: no se pudo cargar la biblioteca", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		}
	}	

	public static void crearLista(JFrame padre) {
		Bean bean = Fachada.crearLista(padre);
		if (bean != null) {
			actualizaReproduccion(bean);
		}
	}
	
	public static void abrirLista(JFrame padre) {
		Bean bean = Fachada.abrirLista(padre);
		if (bean != null) {
			actualizaReproduccion(bean);
		}
	}

	public static void importarCarpeta(JFrame padre) {
		Bean bean = Fachada.importarCarpeta(padre);
		if (bean != null) {
			actualizaReproduccion(bean);
		}
	}

	public static void importarArchivos(JFrame padre) {
		Bean bean = Fachada.importarArchivos(padre);
		if (bean != null) {
			actualizaReproduccion(bean);
		}
	}

	public static void guardar() {
		Fachada.guardar();
	}

	public static void guardaListaComo(JFrame padre) {
		Fachada.guardaListaComo(padre);
	}

	public static void siguiente() {
		Bean bean = Fachada.siguiente();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al avanzar pista", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		} else {
			actualizaReproduccion(bean);
		}
	}

	public static void avanzar() {
		Bean bean = Fachada.avanzar();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al avanzar", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	public static void play() {
		Bean bean = Fachada.play();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al reproducir", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		} else {
			String estado = bean.getEstado();
			if (estado.equals("Reproduciendo")) {
				actualizaEstado("Reproduciendo");
			} else if (estado.equals("Pausado")) {
				actualizaEstado("Pausado");
			}			
			actualizaTablaLista(bean);
		}
	}

	public static void stop() {
		Bean bean = Fachada.stop();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al detener la reproduccion",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		} else {
			if (bean.getEstado().equals("Parado")) {
				actualizaTiempo("00:00", bean.getBiblioteca()
						.getCancionActual().getStringDuracion());
				actualizaProgreso(0, "00:00");
				actualizaEstado("Parado");
				actualizaTablaLista(bean);
			}
		}
	}

	public static void retroceder() {
		Bean bean = Fachada.retroceder();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al retroceder", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	public static void anterior() {
		Bean bean = Fachada.anterior();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error con el boton anterior",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		} else {
			actualizaReproduccion(bean);
		}
	}

	public static void dobleClick(int fila) {
		Bean bean = Fachada.dobleClick(fila);
		if (bean != null) {
			actualizaReproduccion(bean);
		}

	}

	private static void actualizaReproduccion(Bean bean) {
		if (bean.getBiblioteca().getCanciones().size() > 0) {
			setReproducible(true);
			habilitaMenuReproduccion();
			habilitaBotones();
			habilitaProgreso(bean.getBiblioteca().getCancionActual()
					.getDuracion());
			actualizaProgreso(0, "00:00");
			actualizaCaratula(); // Obtener caratula
			File archivo = bean.getArchivo();
			actualizaArchivo(archivo.toString(), archivo.getName());
			int total;
			if (bean.getBiblioteca().getIndiceListaActual() == -1) {
				total = bean.getBiblioteca().getCanciones().size();
			} else {
				total = bean.getBiblioteca().getPlaylistActual().getCanciones()
						.size();
			}
			actualizaPista(Integer.toString(1), Integer.toString(total));
			actualizaTiempo("00:00", bean.getBiblioteca().getCancionActual()
					.getStringDuracion());
			actualizaEstado(bean.getEstado());
			actualizaTablaInfo(bean);
			actualizaTablaLista(bean);
		}
	}
	
	public static void cambiaLista(int idLista, String actual) {
		Bean bean = Fachada.cambiaLista(idLista, actual);
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al cambiar de lista",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		} else {
			actualizaTablaLista(bean);
		}
	}

	public static void cambiaTiempo(int segundos) {
		Bean bean = Fachada.cambiaTiempo(segundos);
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al cambiar el tiempo",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		} else {
			int estado = bean.getPlayer().getStatus();
			if ((estado == BasicPlayer.STOPPED)
					|| (estado == BasicPlayer.OPENED)) {
				actualizaTiempo(tiempoToString(bean.getTiempoActual()), bean
						.getBiblioteca().getCancionActual().getStringDuracion());
			}
		}
	}

	public static void cambiaVolumen(int vol) {
		Bean bean = Fachada.cambiaVolumen(vol);
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al cambiar volumen",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		}
	}

	public static void mute() {
		Bean bean = Fachada.mute();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al hacer mute", "XtremeAudio",
					JOptionPane.ERROR_MESSAGE);
		} else {
			actualizaMute(bean.getPlayer().isMute());
		}
	}

	public static void repetir() {
		Bean bean = Fachada.repetir();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al hacer aleatorio",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		}
	}

	public static void aleatorio() {
		Bean bean = Fachada.aleatorio();
		if (bean == null) {
			JOptionPane.showMessageDialog(null,
					"Se ha producido un error al hacer aleatorio",
					"XtremeAudio", JOptionPane.ERROR_MESSAGE);
		}
	}

	public static void buscar(String texto) {
		Bean bean = Fachada.buscar(texto);
		for (int i = 0; i < bean.getBusqueda().size(); i++) {
			System.out.println(Integer.toString(bean.getBusqueda().get(i)));
		}
		actualizaTablaListaBusqueda(bean);
	}

	// Ordenes a las vistas
	public static void show() {
		vistaPrincipal.show();
	}

	public static void ayuda() {
		vistaAyuda.show();
	}

	public static void editar() {
		Cancion c = Fachada.getBean().getBiblioteca().getCancionActual();
		vistaTags.getFieldAutor().setText(c.getAutor());
		vistaTags.getFieldAlbum().setText(c.getAlbum());
		vistaTags.getFieldTitulo().setText(c.getTitulo());
		vistaTags.getFieldGenero().setText(c.getGenero());
		vistaTags.getFieldAnyo().setText(c.getAnyo());
		vistaTags.getFieldPista().setText(c.getPista());
		vistaTags.show();
	}

	public static void actualizaCaratula() {
		vistaPrincipal.actualizaCaratula();
	}

	public static void actualizaTablaInfo(Bean bean) {
		DefaultTableModel modelo = (DefaultTableModel) vistaPrincipal
				.getTablaInfo().getModel();
		@SuppressWarnings("unchecked")
		Vector<Vector<String>> v = modelo.getDataVector();
		v.elementAt(0).setElementAt(
				bean.getBiblioteca().getCancionActual().getAutor(), 1);
		v.elementAt(1).setElementAt(
				bean.getBiblioteca().getCancionActual().getAlbum(), 1);
		v.elementAt(2).setElementAt(
				bean.getBiblioteca().getCancionActual().getTitulo(), 1);
		v.elementAt(3).setElementAt(
				bean.getBiblioteca().getCancionActual().getGenero(), 1);
		v.elementAt(4).setElementAt(
				bean.getBiblioteca().getCancionActual().getAnyo(), 1);
		v.elementAt(5).setElementAt(
				bean.getBiblioteca().getCancionActual().getPista(), 1);
		v.elementAt(6).setElementAt(
				bean.getBiblioteca().getCancionActual().getStringDuracion(), 1);
		v.elementAt(7).setElementAt(
				bean.getBiblioteca().getCancionActual().getFormato(), 1);
		v.elementAt(8).setElementAt(
				bean.getBiblioteca().getCancionActual().getPath(), 1);
		vistaPrincipal.actualizaTablaInfo(modelo);
	}

	public static void actualizaTablaLista(Bean bean) {
		DefaultTableModel modelo = (DefaultTableModel) vistaPrincipal
				.getTablaLista().getModel();
		int total = modelo.getRowCount(); // Guardamos al principio, pues al
											// borrar se actualiza
		for (int i = 0; i < total; i++)
			modelo.removeRow(0); // Va borrando la primera siempre
		Biblioteca b = bean.getBiblioteca();
		int fila = 0;
		boolean sonando = (b.getIndiceListaActual() == b.getIndiceListaSonando());
		if (b.getIndiceListaActual() == -1) {
			Iterator<Cancion> it = b.getCanciones().iterator();			
			while (it.hasNext()) {
				Cancion c = it.next();
				Vector<Object> v = new Vector<Object>();				
				if ((sonando) && (fila == b.getIndiceCancion())) {
					if (bean.getEstado().equals("Parado")) {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/stop_16x16.png")));
					} else if (bean.getEstado().equals("Reproduciendo")) {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/play_16x16.png")));
					} else {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/pausa_16x16.png")));
					}
				} else {
					v.add(null);
				}
				v.add(c.getTitulo());
				v.add(c.getAutor());
				v.add(c.getAlbum());
				v.add(c.getStringDuracion());
				modelo.addRow(v);
				fila++;
			}
		} else {
			Playlist p = b.getPlaylistActual();
			for (int i = 0; i < p.getCanciones().size(); i++) {
				Cancion c = b.getCanciones().get(p.getIdCancion(i));
				Vector<Object> v = new Vector<Object>();
				if ((sonando) && (fila == p.getIndiceActual())) {
					if (bean.getEstado().equals("Parado")) {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/stop_16x16.png")));
					} else if (bean.getEstado().equals("Reproduciendo")) {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/play_16x16.png")));
					} else {
						v.add(new ImageIcon(Controlador.class.getClassLoader()
								.getResource("img/pausa_16x16.png")));
					}
				} else {
					v.add(null);
				}
				v.add(c.getTitulo());
				v.add(c.getAutor());
				v.add(c.getAlbum());
				v.add(c.getStringDuracion());
				modelo.addRow(v);
				fila++;
			}
		}
		vistaPrincipal.actualizaTablaLista(modelo);
	}

	/**
	 * 
	 * @param bean
	 */
	public static void actualizaTablaListaBusqueda(Bean bean) {
		DefaultTableModel modelo = (DefaultTableModel) vistaPrincipal
				.getTablaLista().getModel();
		int total = modelo.getRowCount(); // Guardamos al principio, pues al
											// borrar se actualiza
		for (int i = 0; i < total; i++)
			modelo.removeRow(0); // Va borrando la primera siempre
		ArrayList<Integer> busqueda = bean.getBusqueda();
		Iterator<Integer> it = busqueda.iterator();
		int fila = 0;
		while (it.hasNext()) {
			int i = it.next();
			Cancion c = bean.getBiblioteca().getCanciones().get(i);
			Vector<Object> v = new Vector<Object>();
			if (fila == bean.getIndiceBusqueda()) {
				if (bean.getEstado().equals("Parado")) {
					v.add(new ImageIcon(Controlador.class.getClassLoader()
							.getResource("img/stop_16x16.png")));
				} else if (bean.getEstado().equals("Reproduciendo")) {
					v.add(new ImageIcon(Controlador.class.getClassLoader()
							.getResource("img/play_16x16.png")));
				} else {
					v.add(new ImageIcon(Controlador.class.getClassLoader()
							.getResource("img/pausa_16x16.png")));
				}
			} else {
				v.add(null);
			}
			v.add(c.getTitulo());
			v.add(c.getAutor());
			v.add(c.getAlbum());
			v.add(c.getStringDuracion());
			modelo.addRow(v);
		}
		vistaPrincipal.actualizaTablaLista(modelo);
	}				
	
	/**
	 * 
	 */
	public static void actualizaDatos() { //Sincronizado con el Timer
		Bean bean = Fachada.getBean();
		int tiempo = bean.getTiempoActual() + 1;
		bean.setTiempoActual(tiempo);
		actualizaProgreso(tiempo, tiempoToString(tiempo));
		Biblioteca b = bean.getBiblioteca();
		actualizaTiempo(tiempoToString(tiempo), b.getCancionActual()
				.getStringDuracion());
		if (tiempo == bean.getBiblioteca().getCancionActual().getDuracion()) {
			if (b.getIndiceListaActual() == -1) {
				if (b.getIndiceCancion() < b.getCanciones().size() - 1) {
					siguiente();
				} else {
					stop();
				}
			} else {
				if (b.getPlaylistActual().getIndiceActual() < b
						.getPlaylistActual().getCanciones().size() - 1) {
					siguiente();
				} else {
					stop();
				}
			}
		}
	}

	public static void actualizaProgreso(int tiempo, String stringTiempo) {
		vistaPrincipal.actualizaProgreso(tiempo, stringTiempo);
	}

	public static void actualizaArchivo(String ruta, String nombre) {
		vistaPrincipal.actualizaArchivo(ruta, nombre);
	}

	public static void actualizaPista(String pistaActual, String numPistas) {
		vistaPrincipal.actualizaPista(pistaActual, numPistas);
	}

	public static void actualizaTiempo(String tiempoActual, String tiempoTotal) {
		vistaPrincipal.actualizaTiempo(tiempoActual, tiempoTotal);
	}

	public static void actualizaEstado(String estado) {
		vistaPrincipal.actualizaEstado(estado);
	}

	public static void actualizaMute(boolean mute) {
		vistaPrincipal.actualizaMute(mute);
	}

	public static void habilitaMenuReproduccion() {
		vistaPrincipal.habilitaMenuReproduccion();
	}

	public static void habilitaBotones() {
		vistaPrincipal.habilitaBotones();
	}

	public static void habilitaProgreso(int duracion) {
		vistaPrincipal.habilitaProgreso(duracion);
	}

	public static void setReproducible(boolean b) {
		vistaPrincipal.setReproducible(b);
	}

	public static void habilitaGuardar() {
		vistaPrincipal.habilitaGuardar();
	}

	private static void creaArbol(Bean bean){
		DefaultMutableTreeNode raiz = new DefaultMutableTreeNode(
				new NodoArbol("Biblioteca", -1), true);
		DefaultTreeModel modelo = new DefaultTreeModel(raiz,
				true);
		if (bean != null) {
			Biblioteca b = bean.getBiblioteca();
			for (int i = 0; i < b.getPlaylists().size(); i++){			
				Playlist p = b.getPlaylist(i);
				raiz.add(new DefaultMutableTreeNode(new NodoArbol(p.getNombre(),i),false));
			}
		}
		vistaPrincipal.creaArbol(modelo);
	}
	
	private static String tiempoToString(int segundos) {
		String m, s;
		Integer mins = segundos / (int) 60;
		Integer segs = segundos % 60;
		m = mins.toString();
		s = segs.toString();
		if (mins < 10) {
			m = "0" + m;
		}
		if (segs < 10) {
			s = "0" + s;
		}
		return (m + ":" + s);
	}

}